package com.bysc.gateway.filter;

import com.alibaba.fastjson.JSONObject;
import com.bysc.commonutils.ResultCode;
import com.bysc.commonutils.Results;
import com.bysc.commonutils.constant.MessageConstant;
import com.bysc.commonutils.utils.JwtUtils;
import com.bysc.gateway.client.UserClient;
import lombok.SneakyThrows;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 全局网关
 */
@Component
public class GatewayFilter implements GlobalFilter, Ordered {
    @Autowired
    private UserClient userClient;

    @Bean
    @ConditionalOnMissingBean
    public HttpMessageConverters messageConverters(ObjectProvider<HttpMessageConverter<?>> converters) {
        return new HttpMessageConverters(converters.orderedStream().collect(Collectors.toList()));
    }

    @SneakyThrows
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1.获取请求参数
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        String originalPath = request.getURI().getPath();
        // 放行相关接口
        if (originalPath.contains("getAnnouncementList")  || originalPath.contains("cmsservice/cms-ai/getReply")
                ||originalPath.contains("websocketservice") || originalPath.contains("login")
                || originalPath.contains("register") || originalPath.contains("getClubs")
                || originalPath.contains("getDeptByClubId")|| originalPath.contains("getDeptByPage")
                || originalPath.contains("getTeacherList")|| originalPath.contains("getActivityList")
                || originalPath.contains("getClubsByPage")|| originalPath.contains("getDeptDetailByDeptId")) {
            return chain.filter(exchange);
        }
        // 放行所有GET请求
        if (request.getMethod().toString().equalsIgnoreCase("GET")) {
            return chain.filter(exchange);
        }

        // 获取业务请求中的Token
        List<String> tokens = request.getHeaders().get("token");

        Results result = Results.error().code(HttpStatus.UNAUTHORIZED.value()).message(MessageConstant.VALIDATETOKEN_ERROR);
        String token;
        // 判断用户是否登录
        if (tokens != null && !StringUtils.isEmpty(tokens.get(0))) {
            token = tokens.get(0);
            // token验证是否有效
            result = checkToken(token);
            if (result.getCode() == ResultCode.SUCCESS) {
                String userId = JwtUtils.getMemberIdByJwtToken(token);
                // 检验是否为管理员
                result = userClient.getUserInfo(userId);
                if (result.getSuccess()) {
                    return chain.filter(exchange);
                }//检验用户是否被禁用
                result = userClient.isDisabled(userId);
                if (result.getSuccess() && !(boolean) result.getData().get("isDisabled")) {
                    return chain.filter(exchange);
                }
            }
        }
        response.setStatusCode(HttpStatus.UNAUTHORIZED); // 状态码
        String s = JSONObject.toJSONString(result);
        DataBuffer wrap = response.bufferFactory().wrap(s.getBytes());
        return response.writeWith(Mono.just(wrap));
    }

    @Override
    public int getOrder() {
        return 1;
    }

    public Results checkToken(String token) {
        // Token为空
        if (token == null || "".equals(token)) {
            return Results.error().code(ResultCode.ERROR);
        }
        // 2)如果token不为空，则校验token是否错误/过期
        try {
            boolean isExpire = JwtUtils.checkToken(token);
        } catch (Exception e) {
            return Results.error().code(ResultCode.ERROR);
        }
        return Results.ok().code(ResultCode.SUCCESS);
    }
}
